package cc.rengu.igas.route.core.realize.payment.impl.upac;

import cc.rengu.igas.channel.upac.biz.impl.UpacCollectionServiceImpl;
import cc.rengu.igas.channel.upac.facade.base.Header;
import cc.rengu.igas.channel.upac.facade.request.CollectionRequest;
import cc.rengu.igas.channel.upac.facade.request.CollectionTransStateQueryRequest;
import cc.rengu.igas.channel.upac.facade.response.CollectionResponse;
import cc.rengu.igas.channel.upac.facade.response.CollectionTransStateQueryResponse;
import cc.rengu.igas.channel.upac.facade.result.Result;
import cc.rengu.igas.route.common.constant.SmartRouteParamConstant;
import cc.rengu.igas.route.common.enums.SmartRouteRspEnums;
import cc.rengu.igas.route.core.realize.payment.DstChannelPaymentService;
import cc.rengu.igas.route.facade.bean.PayerInfo;
import cc.rengu.igas.route.facade.request.IntelligencePaymentRequest;
import cc.rengu.igas.route.facade.request.IntelligencePaymentVerifyRequest;
import cc.rengu.igas.route.facade.request.IntelligenceResultQueryRequest;
import cc.rengu.igas.route.facade.response.IntelligencePaymentResponse;
import cc.rengu.igas.route.facade.response.IntelligencePaymentVerifyResponse;
import cc.rengu.igas.route.facade.response.IntelligenceResultQueryResponse;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.DstChannelCfgMapper;
import cc.rengu.oltp.service.common.dao.impl.DstChannelCfgMapperImpl;
import cc.rengu.oltp.service.common.entity.DstChannelCfg;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.BeanUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSONObject;

/**
 * 全渠道对外收款实现
 *
 * @author lizhangtao
 * @version 1.0.0
 * @date 2020-04-30
 */
public class UpacPaymentServiceImpl implements DstChannelPaymentService {
    private final static String TXN_NUM = "1103000000";
    /**
     * 默认渠道类型 07-互联网
     */
    private final static String DEFAULT_CHANNEL_TYPE = "07";
    /**
     * 通道类型为代收CT  商户选择其开通的产品时取自支付通道信息表T_P_DST_CHANNEL_CFG
     */
    private final static String DST_CHANNEL_TYPE = "CT01";
    private RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    /**
     * 对外收款
     *
     * @param intelligencePaymentRequest
     * @return IntelligencePaymentResponse
     * @throws Exception 调用异常
     * @author xionglz
     * @date 2020-04-30
     */
    @Override
    public IntelligencePaymentResponse payment(IntelligencePaymentRequest intelligencePaymentRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        IntelligencePaymentResponse intelligencePaymentResponse = new IntelligencePaymentResponse();
        intelligencePaymentResponse.setHeader(intelligencePaymentRequest.getHeader());
        intelligencePaymentResponse.setDstChannelId("UPAC");
        intelligencePaymentResponse.setMchntNo(intelligencePaymentRequest.getMchntNo());
        intelligencePaymentResponse.setDstChannelTxnNum(TXN_NUM);
        CollectionRequest collectionRequest = new CollectionRequest();
        collectionRequest.setProdType(DST_CHANNEL_TYPE);
        collectionRequest.setChannelType(DEFAULT_CHANNEL_TYPE);
        collectionRequest.setPayAcctNo(intelligencePaymentRequest.getPayerInfo().getAcctNo());
        collectionRequest.setBillNo(intelligencePaymentRequest.getPayerInfo().getCertId());
        collectionRequest.setBillType("OT");
        collectionRequest.setOrderId(intelligencePaymentRequest.getHeader().getTraceNo());
        collectionRequest.setOrderAmt(intelligencePaymentRequest.getTxnAmt());
        collectionRequest.setOrderCcy(intelligencePaymentRequest.getTxnCrcyCode());
        collectionRequest.setOrderTime(intelligencePaymentRequest.getHeader().getTransDate() + intelligencePaymentRequest.getHeader().getTransTime());
        Header header = new Header();
        BeanUtil.beanCopy(intelligencePaymentRequest.getHeader(), header);
        header.setTxnNum(TXN_NUM);
        collectionRequest.setHeader(header);
        DubboService dubboService = new DubboServiceImpl();
        Result<CollectionResponse> responseResult = (Result<CollectionResponse>) dubboService.callDubboInnerMethod(UpacCollectionServiceImpl.class, "singleCollection", collectionRequest);
        //调用失败结果为空
        if (null == responseResult || null == responseResult.getResult() || !responseResult.isSuccess()) {
            //代付未知不能作为失败处理，只能作为超时处理
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_TO.getRespCode());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, SmartRouteRspEnums.TRANS_TO.getRespDesc());
            intelligencePaymentResponse.setRespCode(SmartRouteRspEnums.TRANS_TO.getRespCode());
            intelligencePaymentResponse.setRespDesc(SmartRouteRspEnums.TRANS_TO.getRespDesc());
            return intelligencePaymentResponse;
        }
        if (OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equals(responseResult.getResult().getRespCode())) {
            xmlTreeUtil.setXmlTreeStringValue(SmartRouteParamConstant.CHANNEL_SEQNUM, responseResult.getResult().getChannelSeqNum());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_ACQ_SUCC.getRespCode());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_ACQ_SUCC.getRespDesc());
            intelligencePaymentResponse.setRespCode(SmartRouteRspEnums.TRANS_ACQ_SUCC.getRespCode());
            intelligencePaymentResponse.setRespDesc(SmartRouteRspEnums.TRANS_ACQ_SUCC.getRespDesc());
        } else {
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, responseResult.getResult().getRespCode());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, responseResult.getResult().getRespDesc());
            intelligencePaymentResponse.setRespCode(responseResult.getResult().getRespCode());
            intelligencePaymentResponse.setRespDesc(responseResult.getResult().getRespDesc());
        }
        return intelligencePaymentResponse;
    }

    /**
     * 对外收款确认，代收无确认
     *
     * @param intelligencePaymentVerifyRequest
     * @return IntelligencePaymentVerifyResponse
     * @throws Exception 调用异常
     * @author xionglz
     * @date 2020-04-30
     */
    @Override
    public IntelligencePaymentVerifyResponse paymentVerify(IntelligencePaymentVerifyRequest intelligencePaymentVerifyRequest) throws Exception {
        throw new BizException(SmartRouteRspEnums.NO_AUTH_ERROR.getRespCode(), SmartRouteRspEnums.NO_AUTH_ERROR.getRespDesc());
    }

    @Override
    public IntelligenceResultQueryResponse query(IntelligenceResultQueryRequest resultQueryRequest) throws Exception {
        IntelligenceResultQueryResponse intelligenceResultQueryResponse = new IntelligenceResultQueryResponse();
        intelligenceResultQueryResponse.setHeader(resultQueryRequest.getHeader());
        intelligenceResultQueryResponse.setDstChannelId("UPAC");
        CollectionTransStateQueryRequest collectionTransStateQueryRequest = new CollectionTransStateQueryRequest();

        collectionTransStateQueryRequest.setChannelType(DEFAULT_CHANNEL_TYPE);
        collectionTransStateQueryRequest.setOrderId(resultQueryRequest.getOrigOrder());
        collectionTransStateQueryRequest.setOrderTime(resultQueryRequest.getOrigTxnDate() + resultQueryRequest.getOrigTxnTime());
        collectionTransStateQueryRequest.setProdType(DST_CHANNEL_TYPE);
        Header header = new Header();
        BeanUtil.beanCopy(resultQueryRequest.getHeader(), header);
        header.setTxnNum("0000000501");
        collectionTransStateQueryRequest.setHeader(header);
        DubboService dubboService = new DubboServiceImpl();
        Result<CollectionTransStateQueryResponse> responseResult = (Result<CollectionTransStateQueryResponse>) dubboService.callDubboInnerMethod(UpacCollectionServiceImpl.class, "collectionTransStateQuery", collectionTransStateQueryRequest);
        //调用失败结果为空
        if (null == responseResult || null == responseResult.getResult()) {
            intelligenceResultQueryResponse.setRespCode(SmartRouteRspEnums.TRANS_FAIL.getRespCode());
            intelligenceResultQueryResponse.setRespDesc(SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            return intelligenceResultQueryResponse;
        }
        BeanUtil.beanCopy(responseResult.getResult(), intelligenceResultQueryResponse);
        intelligenceResultQueryResponse.setOrigRetCode(responseResult.getResult().getOrigRespCode());
        intelligenceResultQueryResponse.setOrigRetMsg(responseResult.getResult().getOrigRespDesc());
        PayerInfo payerInfo = new PayerInfo();
        payerInfo.setAcctName(responseResult.getResult().getPayCardName());
        payerInfo.setAcctNo(responseResult.getResult().getPayAcctNo());
        intelligenceResultQueryResponse.setPayerInfo(payerInfo);
        intelligenceResultQueryResponse.setTxnAmt(responseResult.getResult().getSettleAmt());
        intelligenceResultQueryResponse.setTxnCrcyCode(responseResult.getResult().getSettleCcy());
        intelligenceResultQueryResponse.setSettleDate(responseResult.getResult().getSettleDate());
        intelligenceResultQueryResponse.setDstChannelSsn(responseResult.getResult().getTraceNo());
        String respCode = responseResult.getResult().getRespCode();
        //查询交易本身都未知，原交易状态未知
        if (StringUtil.isEmptyOrNull(respCode) || StringUtil.isEmptyOrNull(responseResult.getResult().getOrigRespCode())) {
            intelligenceResultQueryResponse.setRespCode(SmartRouteRspEnums.TRANS_FAIL.getRespCode());
            intelligenceResultQueryResponse.setRespDesc(SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            return intelligenceResultQueryResponse;
        }
        //查询交易有结果
        else {
            //查询交易成功
            if (OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equalsIgnoreCase(respCode)) {
                String origRespCode = responseResult.getResult().getOrigRespCode();
                String origRespDesc = responseResult.getResult().getOrigRespDesc();
                //原交易状态为成功
                if (OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equalsIgnoreCase(origRespCode)) {
                    intelligenceResultQueryResponse.setStatus("0");
                    intelligenceResultQueryResponse.setOrigRetCode(SmartRouteRspEnums.TRANS_SUCCESS.getRespCode());
                    intelligenceResultQueryResponse.setOrigRetMsg(SmartRouteRspEnums.TRANS_SUCCESS.getRespDesc());
                }
                //原交易状态为未知
                else if (OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode().equalsIgnoreCase(origRespCode)) {
                    intelligenceResultQueryResponse.setStatus("2");
                    intelligenceResultQueryResponse.setOrigRetCode(OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode());
                    intelligenceResultQueryResponse.setOrigRetMsg(OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespDesc());
                }
                //其他状态为交易失败
                else {
                    intelligenceResultQueryResponse.setStatus("1");
                    intelligenceResultQueryResponse.setOrigRetCode(SmartRouteRspEnums.TRANS_FAIL.getRespCode());
                    intelligenceResultQueryResponse.setOrigRetMsg(SmartRouteRspEnums.TRANS_FAIL.getRespDesc() + "[" + origRespCode + "]:" + origRespDesc);
                }
            }
            //查询成功，原交易未知(通道直接设置的查询交易应答码）
            else if (OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode().equalsIgnoreCase(respCode)) {
                intelligenceResultQueryResponse.setRespCode(SmartRouteRspEnums.TRANS_SUCCESS.getRespCode());
                intelligenceResultQueryResponse.setRespDesc(SmartRouteRspEnums.TRANS_SUCCESS.getRespDesc());
                intelligenceResultQueryResponse.setStatus("2");
                intelligenceResultQueryResponse.setOrigRetCode(OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode());
                intelligenceResultQueryResponse.setOrigRetMsg(OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespDesc());
            }
            //查询交易失败
            else {
                intelligenceResultQueryResponse.setRespCode(SmartRouteRspEnums.TRANS_FAIL.getRespCode());
                intelligenceResultQueryResponse.setRespDesc(SmartRouteRspEnums.TRANS_FAIL.getRespDesc() + "[" + respCode + "]:" + responseResult.getResult().getRespDesc());
            }
        }
        return intelligenceResultQueryResponse;
    }

    @Override
    public String getReconKey(IntelligencePaymentRequest intelligencePaymentRequest) throws Exception {
        //全渠道直连银联对账key为 商户号+订单号+yyyyMMddHHmmss（订单时间）
        //若上送了银联商户号则使用银联商户号
        String sysSeqNum = null;
        if (!StringUtil.isEmptyOrNull(intelligencePaymentRequest.getAdditionInfo())) {
            String mchntNo = JSONObject.parseObject(intelligencePaymentRequest.getAdditionInfo()).getString("upacMchntNo");
            sysSeqNum = JSONObject.parseObject(intelligencePaymentRequest.getAdditionInfo()).getString(TreeNodeConstant.SYS_SEQ_NUM);
            if (!StringUtil.isEmptyOrNull(mchntNo) && !StringUtil.isEmptyOrNull(sysSeqNum)) {
                return mchntNo + sysSeqNum;
            }
        }
        //通过prodType查询银联商户号
        DstChannelCfgMapper dstChannelCfgMapper = new DstChannelCfgMapperImpl();
        DstChannelCfg dstChannelCfg = dstChannelCfgMapper.selectDstChannelCfgByPrimaryKey(
                intelligencePaymentRequest.getHeader().getInstId(), intelligencePaymentRequest.getDstChannelId(), DST_CHANNEL_TYPE);
        if (null == dstChannelCfg || StringUtil.isEmptyOrNull(dstChannelCfg.getProviderMchntNo())) {
            rglog.error("根据产品<{}>查询银联全渠道商户号出错", DST_CHANNEL_TYPE);
            throw new BizException(SmartRouteRspEnums.CONFIG_ERROR.getRespCode(), SmartRouteRspEnums.CONFIG_ERROR.getRespDesc());
        }
        return dstChannelCfg.getProviderMchntNo() + sysSeqNum;
    }
}
